{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Examples and applications of the EUtils module     "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The example here below are extracted from (perl code)\n",
    "\n",
    "http://www.ncbi.nlm.nih.gov/books/NBK25498/#chapter3\n",
    "    \n",
    "and used here below to show how \n",
    "- to use BioServices to access to EUtils, the Entrez utilities    \n",
    "- call Etutils in a proper way (e.g., using EPost)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:Initialising Efetch service (REST)\n"
     ]
    }
   ],
   "source": [
    "from bioservices import EUtils\n",
    "e = EUtils()\n",
    "\n",
    "# you should provide your email in one of the 3 following ways:\n",
    "# e = EUTils(email=\"yours\")\n",
    "# e = EUtils(); e.email = \"yours\"\n",
    "# fill the ./config/bioservices/bioservices.cfg with a section\n",
    "#     [user]\n",
    "#     email = yours"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ESearch and ESummary/EFetch example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "Exception",
     "evalue": "(410, u'Gone')",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mException\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-5-4d122a83a4dc>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m \u001b[1;31m# here, we use the history that will populate in results the fields called WebEnv and query_key\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m \u001b[0mresults\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mESearch\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mquery\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0musehistory\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'y'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      8\u001b[0m \u001b[0mresults\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mWebEnv\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[0mresults\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQueryKey\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m/home/cokelaer/Work/github/bioservices/src/bioservices/eutils.pyc\u001b[0m in \u001b[0;36mESearch\u001b[1;34m(self, db, term, **kargs)\u001b[0m\n\u001b[0;32m    550\u001b[0m         \u001b[1;31m# the db and term parameter must also be provided in the params\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    551\u001b[0m         \u001b[1;31m# dict so that other argument are also used... wierd\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 552\u001b[1;33m         \u001b[0mret\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mserv\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun_eSearch\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mterm\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    553\u001b[0m         \u001b[1;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    554\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m/home/cokelaer/Work/virtualenv/lib/python2.7/site-packages/suds_jurko-0.7.dev0-py2.7.egg/suds/client.pyc\u001b[0m in \u001b[0;36m__call__\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m    564\u001b[0m         \u001b[0mclient\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mclientclass\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclient\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmethod\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    565\u001b[0m         \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 566\u001b[1;33m             \u001b[1;32mreturn\u001b[0m \u001b[0mclient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minvoke\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    567\u001b[0m         \u001b[1;32mexcept\u001b[0m \u001b[0mWebFault\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    568\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfaults\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m/home/cokelaer/Work/virtualenv/lib/python2.7/site-packages/suds_jurko-0.7.dev0-py2.7.egg/suds/client.pyc\u001b[0m in \u001b[0;36minvoke\u001b[1;34m(self, args, kwargs)\u001b[0m\n\u001b[0;32m    703\u001b[0m         \u001b[0mmetrics\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"message for '%s' created: %s\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod_name\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimer\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    704\u001b[0m         \u001b[0mtimer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 705\u001b[1;33m         \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msoapenv\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    706\u001b[0m         \u001b[0mtimer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    707\u001b[0m         \u001b[0mmetrics\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"method '%s' invoked: %s\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmethod_name\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimer\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m/home/cokelaer/Work/virtualenv/lib/python2.7/site-packages/suds_jurko-0.7.dev0-py2.7.egg/suds/client.pyc\u001b[0m in \u001b[0;36msend\u001b[1;34m(self, soapenv)\u001b[0m\n\u001b[0;32m    750\u001b[0m         \u001b[1;32mexcept\u001b[0m \u001b[0msuds\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtransport\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTransportError\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    751\u001b[0m             \u001b[0mcontent\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfp\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mread\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mor\u001b[0m \u001b[1;34m\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 752\u001b[1;33m             \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mprocess_reply\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcontent\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhttpcode\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtostr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    753\u001b[0m         \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mprocess_reply\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mreply\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmessage\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mNone\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    754\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m/home/cokelaer/Work/virtualenv/lib/python2.7/site-packages/suds_jurko-0.7.dev0-py2.7.egg/suds/client.pyc\u001b[0m in \u001b[0;36mprocess_reply\u001b[1;34m(self, reply, status, description)\u001b[0m\n\u001b[0;32m    817\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0moptions\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfaults\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    818\u001b[0m                 \u001b[1;31m#TODO: Use a more specific exception class here.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 819\u001b[1;33m                 \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstatus\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdescription\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    820\u001b[0m             \u001b[1;32mreturn\u001b[0m \u001b[0mstatus\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdescription\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    821\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mException\u001b[0m: (410, u'Gone')"
     ]
    }
   ],
   "source": [
    "# Download PubMed records that are indexed in MeSH for both asthma and \n",
    "# leukotrienes and were also published in 2009.\n",
    "query = 'asthma[mesh]+AND+leukotrienes[mesh]+AND+2009[pdat]'\n",
    "db = 'pubmed'\n",
    "\n",
    "# here, we use the history that will populate in results the fields called WebEnv and query_key\n",
    "results = e.ESearch(db, query, usehistory='y')\n",
    "results.WebEnv\n",
    "results.QueryKey"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(eSummaryRequest){\n",
       "   db = None\n",
       "   id = None\n",
       "   WebEnv = None\n",
       "   query_key = None\n",
       "   retstart = None\n",
       "   retmax = None\n",
       "   tool = \"BioServices, 1.3.8\"\n",
       "   email = \"cokelaer@ebi.ac.uk\"\n",
       " }"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# How to figure out the correct parameter name for ESummary ?\n",
    "e.get_esummary_params()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'results' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-4-1cc3019103a8>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# we can now resuse the query and webenv values\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mres\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mESummary\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdb\u001b[0m\u001b[1;33m,\u001b[0m  \u001b[0mquery_key\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mresults\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQueryKey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mWebEnv\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mresults\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mWebEnv\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'results' is not defined"
     ]
    }
   ],
   "source": [
    "# we can now resuse the query and webenv values\n",
    "res = e.ESummary(db,  query_key=results.QueryKey, WebEnv=results.WebEnv)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): eutils.ncbi.nlm.nih.gov\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "1. Zhongguo Dang Dai Er Ke Za Zhi. 2009 Nov;11(11):909-12.\n",
      "\n",
      "[Urinary leukotrience E(4) level in children with asthma].\n",
      "\n",
      "[Article in Chinese]\n",
      "\n",
      "He MJ(1), Chen Q, Liu JM.\n",
      "\n",
      "Author information: \n",
      "(1)Depart\n"
     ]
    }
   ],
   "source": [
    "data = e.EFetch(db,query_key=results.QueryKey, WebEnv=results.WebEnv, rettype=\"abstract\", retmode=\"text\")\n",
    "print(data[0:200])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>EPost and ESummary/EFetch example</h2>\n",
    "- Input: List of Entrez UIDs (integer identifiers, e.g. PMID, GI, Gene ID)\n",
    "- ESummary Output: XML Document Summaries\n",
    "- EFetch Output: Formatted data records (e.g. abstracts, FASTA)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " List of Entrez UIDs (integer identifiers, e.g. PMID, GI, Gene ID)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "db = 'protein'\n",
    "id_list = '194680922,50978626,28558982,9507199,6678417'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "results = e.EPost(db, id_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(reply){\n",
       "   QueryKey = \"1\"\n",
       "   WebEnv = \"NCID_1_311096996_130.14.18.34_9001_1410196505_465456362_0MetA0_S_MegaStore_F_1\"\n",
       " }"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "summary = e.ESummary(db, query_key=results.QueryKey, WebEnv=results.WebEnv)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Resetting dropped connection: eutils.ncbi.nlm.nih.gov\n"
     ]
    }
   ],
   "source": [
    "summary = e.EFetch(db, query_key=results.QueryKey, WebEnv=results.WebEnv, retmode=\"text\", rettype=\"fasta\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">gi|194680922|ref|XP_603356.4| PREDICTED: similar to Thyroid peroxidase precursor (TPO) [Bos taurus]\n",
      "METAEVQKLPPTNRETRSVPSKKRGCGWVMEGHRQVLESLTPLKTTVLFTRNFMQKSQSQSLNISGPRVV\n",
      "RGRWWFGPGLVWSQLEEGLWADGARFPVISAQKRCWQMRARAVLGVVLAVTCAGAVFSFLLRPGGLLWGE\n",
      "TEESQVRGIVEASRLLVDKSVYAAMRRNLHKREVISPAQLLSFSKLPEPTSRAASRAAEVMEASVQEAAR\n",
      "RGHLRSGPSQLPTDALSEGLLSAIANLSGCLPYMLPPRCPATCLASKYRLISGACNNRDHPRWGASNTAL\n",
      "ARWLPPAYEDGISEPRGWNPHFLYKGFPLPPVREVTRRIIHASNEAVTGDDRYSDLLTAWGQYIDHDIAF\n",
      "TPQSAAPSAPWVGADCQLTCEPRSPCFPIQLPANAAGPACLPFY\n"
     ]
    }
   ],
   "source": [
    "print(summary[0:500])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>ELink – ESummary/Efetch</h2>\n",
    "\n",
    "- Input: List of Entrez UIDs in database A (integer identifiers, e.g. PMID, GI, Gene ID)\n",
    "- ESummary Output: Linked XML Document Summaries from database B\n",
    "- EFetch Output: Formatted data records (e.g. abstracts, FASTA) from database B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "dbfrom = 'protein'\n",
    "db = 'gene'\n",
    "linkname = 'protein_gene'\n",
    "# here is the list of identifiers in protein database (GIs)\n",
    "id_list = '194680922,50978626,28558982,9507199,6678417'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NCID_1_311097941_130.14.18.34_9001_1410196510_1820950996_0MetA0_S_MegaStore_F_1"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results = e.ELink(dbfrom, sid=id_list, db=db, linkname=linkname, cmd=\"neighbor_history\")\n",
    "QueryKey = results.LinkSet[0].LinkSetDbHistory[0].QueryKey\n",
    "\n",
    "WebEnv = results.LinkSet[0].WebEnv\n",
    "WebEnv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# include the previous results (WEbEnv and querykey)  in a esummary call\n",
    "summary = e.ESummary(db=db, query_key=QueryKey, WebEnv=WebEnv)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(ItemType){\n",
       "   _Type = \"String\"\n",
       "   _Name = \"Description\"\n",
       "   ItemContent = \"thyroid peroxidase\"\n",
       " }"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example of contenst that can be extracted:\n",
    "docsum = summary.DocSum[0]\n",
    "docsum.Item[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Resetting dropped connection: eutils.ncbi.nlm.nih.gov\n"
     ]
    }
   ],
   "source": [
    "data = e.EFetch(db=db, query_key=QueryKey, WebEnv=WebEnv, rettype=\"xml\", retmode=\"xml\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Element 'Entrezgene_track-info' at 0x5415910>,\n",
       " <Element 'Entrezgene_type' at 0x5415d10>,\n",
       " <Element 'Entrezgene_source' at 0x5415ad0>,\n",
       " <Element 'Entrezgene_gene' at 0x52f68d0>,\n",
       " <Element 'Entrezgene_prot' at 0x521f710>,\n",
       " <Element 'Entrezgene_summary' at 0x521f590>,\n",
       " <Element 'Entrezgene_location' at 0x521f390>,\n",
       " <Element 'Entrezgene_gene-source' at 0x521fa90>,\n",
       " <Element 'Entrezgene_locus' at 0x521fad0>,\n",
       " <Element 'Entrezgene_properties' at 0x45a5710>,\n",
       " <Element 'Entrezgene_homology' at 0x45cbcd0>,\n",
       " <Element 'Entrezgene_comments' at 0x4761090>,\n",
       " <Element 'Entrezgene_unique-keys' at 0x95d99d0>,\n",
       " <Element 'Entrezgene_xtra-index-terms' at 0x95d9790>,\n",
       " <Element 'Entrezgene_xtra-properties' at 0x95d9650>]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.root.getchildren()[0].getchildren()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>ESearch - ELink - ESummary/EFetch</h2>\n",
    "- Input: Entrez text query in database A\n",
    "- ESummary Output: Linked XML Document Summaries from database B\n",
    "- EFetch Output: Formatted data records (e.g. abstracts, FASTA) from database B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Download protein FASTA records linked to abstracts published \n",
    "# in 2009 that are indexed in MeSH for both asthma and \n",
    "# leukotrienes.\n",
    "db1 = 'pubmed'\n",
    "db2 = 'protein'\n",
    "linkname = 'pubmed_protein'\n",
    "query = 'asthma[mesh]+AND+leukotrienes[mesh]+AND+2009[pdat]'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "results = e.ESearch(db1, term=query, usehistory='y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#call ELink with previous key and env\n",
    "output = e.ELink(db1, db=db2, query_key=results.QueryKey, WebEnv=results.WebEnv, \n",
    "                 cmd=\"neighbor_history\", linkname=linkname)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "WebEnv2 = output.LinkSet[0].WebEnv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "QueryKey2 = output.LinkSet[0].LinkSetDbHistory[0].QueryKey"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "docsums = e.ESummary(db=db2, query_key=QueryKey2, WebEnv=WebEnv2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Resetting dropped connection: eutils.ncbi.nlm.nih.gov\n"
     ]
    }
   ],
   "source": [
    "data = e.EFetch(db=db2, query_key=QueryKey2, WebEnv=WebEnv2, rettype=\"fasta\", retmode=\"text\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">gi|16924014|ref|NP_476492.1| C-C motif chemokine 17 precursor [Rattus norvegicus]\n",
      "MMSLQMLLLAALLLGTSLQHASAARATNVGRECCLDYFKGAIPIRKLVTWFRTSVECPKDAIVFETVQGR\n",
      "LICTDPKDKHVKKAIRHLKNQRL\n",
      "\n",
      ">gi|8392897|ref|NP_058956.1| arachidonate 5-lipoxygenase-activating protein [Rattus norvegicus]\n",
      "MDQEAVGNVVLLAIVTLISVVQNAFFAHKVELESKAQSGRSFQRTGTLAFERVYTANQNCVDAYPTFLVV\n",
      "LWTAGLLCSQVPAAFAGLMYLFVRQKYFVGYLGERTQSTPGYIFGKRIILFLFLMSLAGILNHYLIFFFG\n",
      "SDFENYIRTITTTISPLLLIP\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>Application1: Converting GI numbers to accession numbers </h2>\n",
    "- Goal: Starting with a list of nucleotide GI numbers, prepare a set of corresponding accession numbers.\n",
    "- Solution: Use EFetch with &retttype=acc\n",
    "- Input: $gi_list – comma-delimited list of GI numbers\n",
    "- Output: List of accession numbers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Resetting dropped connection: eutils.ncbi.nlm.nih.gov\n"
     ]
    }
   ],
   "source": [
    "gi_list = '24475906,224465210,50978625,9507198';\n",
    "output = e.EFetch('nucleotide', gi_list, rettype=\"acc\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NM_009417.2\n",
      "NM_000547.4\n",
      "NM_001003009.1\n",
      "NM_019353.1\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#  The order of the accessions in the output will be the same order as the GI numbers in $gi_list."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Application 2: Converting accession numbers to data \n",
    "- Goal: Starting with a list of protein accession numbers, return the sequences in FASTA format.\n",
    "- Solution: Create a string consisting of items separated by 'OR', where each item is an accession number followed by '[accn]'. Example: accn1[accn]+OR+accn2[accn]+OR+accn3[accn]+OR+…\n",
    "- Submit this string as a &term in ESearch, then use EFetch to retrieve the FASTA data.\n",
    "- Input: $acc_list – comma-delimited list of accessions\n",
    "- Output: FASTA data "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "acc_list = 'NM_009417,NM_000547,NM_001003009,NM_019353'\n",
    "query = \"+OR+\".join(acc_list.split(\",\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "results = e.ESearch(db='nucleotide', term=query, usehistory='y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(NCID_1_311102141_130.14.18.34_9001_1410196532_664070211_0MetA0_S_MegaStore_F_1,\n",
       " 1)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results.WebEnv, results.QueryKey\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Resetting dropped connection: eutils.ncbi.nlm.nih.gov\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ">gi|253735815|ref|NM_000547.5| Homo sapiens thyroid peroxidase (TPO), transcript variant 1, mRNA\n",
      "GGAAGGCAATTAAGGCGCCCATTTCAGAAGAGTTACAGCCGTGAAAATTACTCAGCAGTGCAGTTGGCTG\n",
      "AGAAGAGGAAAAAAGGTCAGAATGAGAGCGCTCGCTGTGCTGTCTGTCACGCTGGTTATGGCCTGCACAG\n",
      "AAGCCTTCTTCCCCTTCATCTCGAGAGGGAAAGAACTCCTTTGGGGAAAGCCTGAGGAGTCTCGTGTCTC\n",
      "TAGCGTCTTGGAGGAAAGCAAGCGCCTGGTGGACACCGCCATGTACGCCACGATGCAGAGAAACCTCAAG\n",
      "AAAAGAGGAATCCTTTCTCCAGCTCAGCTTCTGTCTTTTTCCAAACTTCCTGAGCCAACAAGCGGAGTGA\n",
      "TTGCCCGAGCAGCAGAGATAATGGAAACATCAATACAAGCGATGAAAA\n"
     ]
    }
   ],
   "source": [
    "# Note that there is maybe a typo on the NCBI website where protein is used in place of nucleotide. \n",
    "# If we set db=protein, we get a bd request response\n",
    "data = e.EFetch('nucleotide', sid=None, query_key=results.QueryKey, WebEnv=results.WebEnv, rettype='fasta', retmode='text')\n",
    "print(data[0:500])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'OK'"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e._efetch.last_response.reason"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>Application 3: Retrieving large datasets </h2>\n",
    "- Goal: Download all chimpanzee mRNA sequences in FASTA format (>50,000 sequences).\n",
    "- Solution: First use ESearch to retrieve the GI numbers for these sequences and post them on the History server, then use multiple EFetch calls to retrieve the data in batches of 500.\n",
    "- Input: query – chimpanzee[orgn]+AND+biomol+mrna[prop]\n",
    "- Output: A file named \"chimp.fna\" containing FASTA data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "query = 'chimpanzee[orgn]+AND+biomol+mrna[prop]'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "output = e.ESearch(db='nucleotide', term=query, usehistory='y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "156307"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# there are lots of entries and we get only 20 by default\n",
    "output.Count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(NCID_1_311107112_130.14.22.215_9001_1410196538_271370888_0MetA0_S_MegaStore_F_1,\n",
       " 1)"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "output.WebEnv, output.QueryKey"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Resetting dropped connection: eutils.ncbi.nlm.nih.gov\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 batches out of 4 done\n",
      "2 batches out of 4 done\n",
      "3 batches out of 4 done\n",
      "4 batches out of 4 done\n"
     ]
    }
   ],
   "source": [
    "# very slow and large file. For demonstration, let us get only 4 batches of 500 sequences\n",
    "retmax = 500\n",
    "output.Count=1501\n",
    "with open('chimp.rna', 'w') as fh:\n",
    "    # retrieve data in batch of 500\n",
    "    for i in range(0, int(output.Count)/retmax + 1):\n",
    "        data = e.EFetch('nucleotide', WebEnv=output.WebEnv, retstart=i*retmax, query_key=output.QueryKey, \n",
    "                 retmax=retmax, retmode='text', rettype='fasta')\n",
    "        fh.write(data)\n",
    "        print(\"{0} batches out of {1} done\".format(i+1, int(output.Count)/retmax+1))\n",
    "\n",
    "# delete the file\n",
    "#import os\n",
    "#os.remove('chimp.rna')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>Application 4: Finding unique sets of linked records for each member of a large dataset</h2>\n",
    "- Goal: Download separately the SNP rs numbers (identifiers) for each current gene on human chromosome 20.\n",
    "- Solution: First use ESearch to retrieve the Gene IDs for the genes, and then assemble an ELink URL where each Gene ID is submitted as a separate &id parameter.\n",
    "- Input: query – human[orgn]+AND+20[chr]+AND+alive[prop]\n",
    "- Output: A file named \"snp_table\" containing on each line the gene id followed by a colon (\":\") followed by a comma-delimited list of the linked SNP rs numbers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "query = 'human[orgn]+AND+20[chr]+AND+alive[prop]'\n",
    "db1 = 'gene'\n",
    "db2 = 'snp'\n",
    "linkname = 'gene_snp'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notes: The retmax parameter in the ESearch call is set to 5000, as this is a reasonable limit to the number of IDs to send to ELink in one request (if you send 5000 IDs, you are effectively performing 5000 ELink operations). If you need to link more than 5000 records, add &retstart to the ESearch call and repeat the entire procedure for each batch of 5000 IDs, incrementing &retstart for each batch like in application 3.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "output = e.ESearch(db=db1, term=query, usehistory='y', RetMax=5000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "ids = output.IdList.Id[0:10]  # only 10 ids to speed up the example\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, we retrieve 200 identifiers using the ELink method, which is based on WSDL. \n",
    "THe number of identifiers is limited to 200 with this service"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "results = e.ELink(db1, db=db2, linkname=linkname, sid=ids)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[598, 958, 1457, 1471, 1869, 2778, 4318, 5621, 6714, 6790]"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results.LinkSet[0].IdList.Id  # DO NOT print the entire structure, it's very large."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On NCBI page, they use the REST service instead. You can manually call the service as follows so thast you can use HTTP POST request. With REST and a HTTP post request, you can get 5000 identifiers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:Initialising elink service (REST)\n"
     ]
    }
   ],
   "source": [
    "from bioservices import REST\n",
    "elink = REST(\"elink\", url = 'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): eutils.ncbi.nlm.nih.gov\n"
     ]
    }
   ],
   "source": [
    "ids = output.IdList.Id[0:00]\n",
    "\n",
    "res = elink.http_post(\"elink.fcgi\", frmt='xml', \n",
    "                params={'dbfrom':db1, 'db':db2, 'id':ids, 'linkname':linkname, 'retmode':'text'}, \n",
    "                headers={'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent':'elink'} )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "res = elink.easyXML(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "identifiers = {}\n",
    "\n",
    "for link in res.root.getchildren():\n",
    "    this_id = link.getchildren()[1].getchildren()[0].text\n",
    "    links = [this.find('Id').text for this in link.find('LinkSetDb').findall('Link')]\n",
    "    identifiers[this_id] = links[:]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "identifiers.keys()[0:10]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "487"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(identifiers['4318'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING: pylab import has clobbered these variables: ['e']\n",
      "`%matplotlib` prevents importing * from pylab and numpy\n"
     ]
    }
   ],
   "source": [
    "# plot the histogram of the number of links for each identifier\n",
    "%pylab inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\ngLAHAAv8P7Z3zthnjJJpAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0xcc5e5e50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "_ = hist([len(identifiers[k]) for k in identifiers.keys()], 50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
